package com.ehome.poct.core.service.pay;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ehome.exception.RpcException;
import com.ehome.paymentcenter.api.pay.BasePayReqCO;
import com.ehome.paymentcenter.api.pay.BaseRspCO;
import com.ehome.paymentcenter.api.pay.domain.PayExtend;
import com.ehome.paymentcenter.api.pay.scan.ScanPayReqCO;
import com.ehome.poct.core.api.constant.enums.ScanTypeEnums;
import com.ehome.poct.core.api.dto.order.UnificationPayReqDTO;
import com.ehome.poct.core.api.vo.order.PayChannelRespVO;
import com.ehome.poct.core.constant.PayBizCodeEnums;
import com.ehome.poct.core.utils.EHomeAssert;
import com.ehome.web.entity.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

/**
 * @auther: kuiba.peng
 * @date: 2022/10/28 11:48
 * @description:
 */
@Component("AuthCodePayStrategy")
@Slf4j
public class AuthCodePayStrategy extends AbstractPayStrategy<ScanPayReqCO, BaseRspCO> {

    @Override
    public PayChannelRespVO<BaseRspCO> pay(ScanPayReqCO payReqDTO) {
        log.info("authCode pay request:[{}]", JSONUtil.toJsonStr(payReqDTO));
        PayChannelRespVO<BaseRspCO> respVO = new PayChannelRespVO<>();
        respVO.setScanType(ScanTypeEnums.B2C);
        String resp;
        try {
            resp = getPayClient().scan(payReqDTO);
            log.info("authCode pay response:[{}]", resp);
        } catch (RpcException rpcException) {
            respVO.setBusiCode(rpcException.getBusiCode());
            respVO.setMsg(rpcException.getMsg());
            return respVO;
        } catch (Exception e) {
            respVO.setBusiCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            return respVO;
        }
        ResponseWrapper<BaseRspCO> responseWrapper = JSONUtil.toBean(resp, new TypeReference<ResponseWrapper<BaseRspCO>>() {
        }, false);
        respVO.setScanType(ScanTypeEnums.B2C);
        respVO.setData(responseWrapper.getData());
        respVO.setBusiCode(responseWrapper.getBusiCode());
        respVO.setMsg(responseWrapper.getMsg());
        return respVO;
    }

    @Override
    public PayChannelRespVO<BaseRspCO> pay(UnificationPayReqDTO payReqDTO) {
        EHomeAssert.isTrue(StrUtil.isNotBlank(payReqDTO.getAuthCode()), PayBizCodeEnums.AUTH_CODE_NOT_NULL);
        BasePayReqCO basePayReqCO = unificationPayMapping.toBasePayReq(payReqDTO);
        ScanPayReqCO scanPayReqCO = BeanUtil.copyProperties(basePayReqCO, ScanPayReqCO.class);
        scanPayReqCO.setAuthCode(payReqDTO.getAuthCode());
        scanPayReqCO.setTimeoutExpress(payReqDTO.getTimeoutExpress());

        PayExtend payExtend = getPayExtend(payReqDTO.getOrderItemList(), payReqDTO.getProfitsRecordList(), payReqDTO.getPayMoney());
        scanPayReqCO.setPayExtend(payExtend);
        log.info("authCode pay payExtend:[{}]", JSONUtil.toJsonStr(payExtend));

        return pay(scanPayReqCO);
    }

    @Override
    public ScanTypeEnums getSupportType() {
        return ScanTypeEnums.B2C;
    }


    @Override
    public boolean supports(Object payReqDTO) {
        return payReqDTO instanceof ScanPayReqCO;
    }
}
